package de.fhhof.robot.control.impl;

import java.util.Scanner;

import de.fhhof.robot.control.ApplicationStorage;
import de.fhhof.robot.control.Color;
import de.fhhof.robot.control.ConcreateWrokFlowCommand;
import de.fhhof.robot.control.ConnectionFactory;
import de.fhhof.robot.control.IControlToRobot;
import de.fhhof.robot.control.IMessage;
import de.fhhof.robot.control.InvalidOperation;
import de.fhhof.robot.control.Message;
import de.fhhof.robot.control.cmd.concreate.AssemblyState;
import de.fhhof.robot.control.common.CommonConstants;
import de.fhhof.robot.control.common.Utility;
import de.fhhof.robot.control.net.Connection;
import de.fhhof.robot.control.net.IConnection;

public class ControlToRobot implements IControlToRobot {

	private static IConnection robotConnection = null;
	
	public static IConnection getRobotConnection(){
		if(robotConnection == null){
			robotConnection = ConnectionFactory.getConnection(CommonConstants.ROBOT_PORT ,CommonConstants.CONTROL, CommonConstants.ROBOT);
		}
		
		return robotConnection;
	}
	
	
	@Override
	public void putEmptyPalleteToTransferPoint(IMessage msg) {
		System.out.print("Please place an empty palate to transfer point and press 'y/Y': ");
		 Scanner in = new Scanner(System.in);
		 while(in.hasNext()){
			 String token = in.next();
			 if(token.toLowerCase().equals("y")){
				 break;
			 }
		 }
	}

	@Override
	public void putSmartiePalleteToRobotControl(IMessage msg,AssemblyState assemblyState) {
		
		IMessage message = new Message("K001", "");
		IConnection robotConn = getRobotConnection();
		System.out.println("Putting smarties palate to robot control ");
		
        if(!assemblyState.getMsgPutEmptyPalateToRobot().isSent()){
        	robotConn.send(message);
        	assemblyState.getMsgPutEmptyPalateToRobot().setSent(true);
        	ApplicationStorage.getAssemblyState().store(assemblyState, CommonConstants.STORAGE_FILE_NAME);
        }
        IMessage ack1 = null;
        if(!assemblyState.getMsgPutEmptyPalateToRobot().isAck1Received()){
            ack1 = robotConn.receive();
            if(ack1 == null ){
            	System.out.println("Expected ack1 but got null");
            	throw new InvalidOperation();
            }
            if(!ack1.getCommand().equals("A001")){
            	System.out.println("Expected ack1: A001 but got "+ ack1.getCommand());
            	throw new InvalidOperation();
            }                    
        	assemblyState.getMsgPutEmptyPalateToRobot().setAck1Received(true);
        	assemblyState.getMsgPutEmptyPalateToRobot().setAck1(ack1);
        	
        	ApplicationStorage.getAssemblyState().store(assemblyState, CommonConstants.STORAGE_FILE_NAME);
        }else{
        	ack1 = assemblyState.getMsgPutEmptyPalateToRobot().getAck1();
        }
        
        IMessage ack2 = null;
        if(!assemblyState.getMsgPutEmptyPalateToRobot().isAck2Received()){
            ack2 = robotConn.receive();
            if(ack2 == null ){
            	System.out.println("Expected ack2 but got null");
            	throw new InvalidOperation();
            }
            if(!ack2.getCommand().equals("A002")){
            	System.out.println("Expected ack2: A002 but got "+ ack2.getCommand());
            	throw new InvalidOperation();
            }                    
        	assemblyState.getMsgPutEmptyPalateToRobot().setAck2Received(true);
        	assemblyState.getMsgPutEmptyPalateToRobot().setAck2(ack2);
        	
        	ApplicationStorage.getAssemblyState().store(assemblyState, CommonConstants.STORAGE_FILE_NAME);                    
        }
        else{
        	ack2 = assemblyState.getMsgPutEmptyPalateToRobot().getAck2();
        }        
		//System.out.println();

		/** F000 = msg not recognized , F001 = command not executed */
		if(this.hasInvalidResponse(ack1, ack2)){
			throw new InvalidOperation();
		}

	}
	
	public static void main(String args[]){
		
		
		ControlToRobot s = new ControlToRobot();
		s.putEmptyPalleteToTransferPoint(null);
		
	}


	@Override
	public void removeSmartiesPaleteFromRobotControl(IMessage msg,AssemblyState assemblyState) {
		IMessage message = new Message("K004", "");
		IConnection robotConn = getRobotConnection();
		System.out.println("Removing smarties palate from robot ");
		
        if(!assemblyState.getMsgRemovePalateFromRobot().isSent()){
        	robotConn.send(message);
        	assemblyState.getMsgRemovePalateFromRobot().setSent(true);
        	ApplicationStorage.getAssemblyState().store(assemblyState, CommonConstants.STORAGE_FILE_NAME);
        }
        IMessage ack1 = null;
        if(!assemblyState.getMsgRemovePalateFromRobot().isAck1Received()){
            ack1 = robotConn.receive();
            if(ack1 == null ){
            	System.out.println("Expected ack1 but got null");
            	throw new InvalidOperation();
            }
            if(!ack1.getCommand().equals("A001")){
            	System.out.println("Expected ack1: A001 but got "+ ack1.getCommand());
            	throw new InvalidOperation();
            }                    
        	assemblyState.getMsgRemovePalateFromRobot().setAck1Received(true);
        	assemblyState.getMsgRemovePalateFromRobot().setAck1(ack1);
        	
        	ApplicationStorage.getAssemblyState().store(assemblyState, CommonConstants.STORAGE_FILE_NAME);
        }else{
        	ack1 = assemblyState.getMsgRemovePalateFromRobot().getAck1();
        }
        IMessage ack2 = null;
        if(!assemblyState.getMsgRemovePalateFromRobot().isAck2Received()){
            ack2 = robotConn.receive();
            if(ack2 == null ){
            	System.out.println("Expected ack2 but got null");
            	throw new InvalidOperation();
            }
            if(!ack2.getCommand().equals("A002")){
            	System.out.println("Expected ack2: A002 but got "+ ack2.getCommand());
            	throw new InvalidOperation();
            }                    
        	assemblyState.getMsgRemovePalateFromRobot().setAck2Received(true);
        	assemblyState.getMsgRemovePalateFromRobot().setAck2(ack2);
        	
        	ApplicationStorage.getAssemblyState().store(assemblyState, CommonConstants.STORAGE_FILE_NAME);                    
        }
        else{
        	ack2 = assemblyState.getMsgRemovePalateFromRobot().getAck2();
        }        
/*		System.out.println();
		robotConn.send(message);
		IMessage ack1 = robotConn.receive();

		*//** F000 = msg not recognized , F001 = command not executed *//*
		IMessage ack2 = null;
		
		if(ack1 != null && ack1.getCommand().startsWith("A001")){
			ack2 = robotConn.receive();
		}*/
		/** F000 = msg not recognized , F001 = command not executed */
		if(this.hasInvalidResponse(ack1, ack2)){
			throw new InvalidOperation();
		}
		
	}


	@Override
	public void removeEmptyPalateFromTransferPoint(IMessage msg) {
		System.out.print("Please remove the smarties palate from transfer point and press 'y/Y':");
		 Scanner in = new Scanner(System.in);
		 while(in.hasNext()){
			 String token = in.next();
			 if(token.toLowerCase().equals("y")){
				 break;
			 }
		 }
		
	}
	private boolean hasInvalidResponse(IMessage ack1, IMessage ack2){
		return Utility.hasInvalidResponse(ack1, ack2);
	}
}
